import Global from './global'

export function ParamArr(data) {
  // 系统键名
  const IDD_Return = '{50043442-8A69-4A6B-A8B5-61F882EDE4F3}'
  const IDD_DMName = '{9F8E5ECB-5976-4315-B8F3-43B8502B694D}'
  const IDD_lpName = '{2881E26D-62CE-4937-B4BB-8998440417C4}'
  // const IDD_lpGuid = '{12455C51-A578-4538-8105-CF984177BBDD}'
  // const IDD_IsZLib = '{8202DA71-3234-4280-9949-45DA9B8B6651}'
  const IDD_Message = '{BBA7501B-B7A9-492A-96EC-4E44C310832C}'
  const IDD_GlobalID = '{9D81EE66-3CD3-428B-BB3A-F67111F70CAE}'
  // const IDD_SessionID = '{4C87BA17-4399-4AD6-BFBC-6102A7D37E05}'
  // const IDD_IsExcept = '{D28BCBFF-CCB9-4664-9B2C-770753786D6C}'
  const IDD_IsSocket = '{8B8C08DD-CD0D-4F3C-8440-4C271D701FCF}'

  // 数量类型
  const vtInteger = 0 // 整形
  const vtBoolean = 1 // 布尔型
  const vtExtended = 3 // 浮点型
  const vtString = 4 // 字符串
  const vtPointer = 5 // 二进制数据流(表格)
  const vtObject = 7 // 字符串列表
  const vtHexstr = 8 // 轩换为十六进制字符串
  const vtInt64 = 16 // 64位整形
  const vtParam = 18 // ParamArr
  const vtTable = 19 // MemoryTable/SQLTable
  this.dataJson = {}
  this.init = function() {
    if (data) {
      this.dataJson = {}
      if (data[IDD_IsSocket]) {
        data = this.socketToPar(data)
      }
      for (var i = 0; i < data.length; i++) {
        this.dataJson[data[i].Name] = [data[i].Type, data[i].Value]
      }
    }
  }

  this.getData = function(name) {
    return this.dataJson[name] || this.dataJson[name.toUpperCase()]
  }

  this.parseStr = function(dataStr) {
    this.parseJson(JSON.parse(dataStr))
  }

  this.parseJson = function(data) {
    this.dataJson = {}
    for (var i = 0; i < data.length; i++) {
      this.dataJson[data[i].Name] = [data[i].Type, data[i].Value]
    }
  }

  // isStringToHex 不将字符串类型 改为 十六进制
  this.toJson = function(isStringToHex) {
    isStringToHex = (process.env.NODE_ENV === 'development') // todo 调试阶段开启，项目完成后要关闭
    // isStringToHex = true // todo 调试阶段开启，项目完成后要关闭
    var json = []
    for (var key in this.dataJson) {
      // 字符串转为十六进制
      if (!isStringToHex && this.dataJson[key][0] === vtString) {
        json.push({
          Name: key,
          Type: vtHexstr,
          Value: Global.stringToHex(this.dataJson[key][1])
        })
      } else {
        json.push({
          Name: key,
          Type: this.dataJson[key][0],
          Value: this.dataJson[key][1]
        })
      }
    }
    return JSON.stringify(json)
  }

  this.getReturn = function() {
    return this.getStr(IDD_Return)
  }

  this.setReturn = function(value) {
    return this.setStr(IDD_Return, value)
  }

  this.getDMName = function() {
    return this.getStr(IDD_DMName)
  }

  this.getLPName = function() {
    return this.getStr(IDD_lpName)
  }

  this.setDMName = function(name) {
    this.setStr(IDD_DMName, name)
  }

  this.setLPName = function(name) {
    this.setStr(IDD_lpName, name)
  }

  this.getMsgId = function() {
    return this.getInt(IDD_Message)
  }

  this.setMsgId = function(value) {
    this.setInt(IDD_Message, value)
  }

  this.getGlobalId = function() {
    return this.getStr(IDD_GlobalID)
  }

  this.setGlobalId = function(value) {
    this.setStr(IDD_GlobalID, value)
  }

  this.getStr = function(name) {
    var data = this.getData(name)
    if (data) {
      if (data[0] === vtString || data[0] === vtPointer) {
        return data[1]
      } else if (data[0] === vtHexstr) {
        return Global.hextoString(data[1])
      } else {
        return ''
      }
    } else {
      return ''
    }
  }

  this.setStr = function(name, value) {
    if (value === undefined || value === null) {
      value = ''
    }
    this.dataJson[name] = [vtString, value]
  }

  this.getInt = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtInteger)) {
      return parseInt(data[1])
    } else {
      return 0
    }
  }

  this.setInt = function(name, value) {
    this.dataJson[name] = [vtInteger, value]
  }

  this.getInt64 = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtInt64)) {
      return data[1]
    } else {
      return 0
    }
  }

  this.setInt64 = function(name, value) {
    this.dataJson[name] = [vtInt64, value]
  }

  this.getFloat = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtExtended)) {
      return parseFloat(data[1])
    } else {
      return 0
    }
  }

  this.setFloat = function(name, value) {
    this.dataJson[name] = [vtExtended, value]
  }

  this.getBool = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtBoolean)) {
      return (data[1] === true)
    } else {
      return 0
    }
  }

  this.setBool = function(name, value) {
    this.dataJson[name] = [vtBoolean, !!value]
  }

  this.getTable = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtPointer || data[0] === vtTable)) {
      return data[1]
    } else {
      return null
    }
  }
  this.setTable = function(name, value) {
    this.dataJson[name] = [vtTable, value]
  }
  this.getStrList = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtObject)) {
      return data[1].trim().split('\r\n').map(function(a) {
        return a.trim()
      })
    } else {
      return []
    }
  }

  this.setStrList = function(name, value) {
    // 使用原型链判断，Instanceof 在夸window情况会异常
    if (Object.prototype.toString.call(value) === '[object Array]') {
      value = value.join('\r\n')
    }
    this.dataJson[name] = [vtObject, value]
  }

  /**
   * 获取二进制字符串
   * @name name
   */
  this.getBlobStr = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtPointer)) {
      return Global.hextoString(data[1])
    } else {
      return ''
    }
  }
  /**
   * 获取文件转换为blob链接
   * @name name
   */
  this.getFileToBlobUrl = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtPointer)) {
      return Global.hexFileToBlob(data[1])
    } else {
      return ''
    }
  }
  this.setBlobStr = function(name, value) {
    this.dataJson[name] = [vtPointer, Global.stringToHex(value)]
  }

  this.setParam = function(name, value) {
    this.dataJson[name] = [vtParam, value.toJson()]
  }

  this.getParam = function(name) {
    var data = this.getData(name)
    if (data && (data[0] === vtPointer || data[0] === vtParam)) {
      return (new ParamArr(Global.parseWebJson(data[1])))
    } else {
      return (new ParamArr())
    }
  }

  this.has = function(name) {
    return (this.getData(name) !== undefined)
  }

  this.remove = function(name) {
    delete this.dataJson[name]
  }

  this.clear = function() {
    this.dataJson = {}
  }
  // 将socket数据转换为vPar 可以解析的数据格式
  this.socketToPar = function(data) {
    var res = []
    var response = data.response
    // 错误信息
    res.push({
      Name: IDD_Return,
      Type: vtString,
      Value: response.msg || ''
    })
    // 消息推送 的消息码
    res.push({
      Name: IDD_Message,
      Type: vtInteger,
      Value: response.msgid
    })
    // 数据
    var bodyData = data.body
    var keys = Object.keys(bodyData)
    for (var i = 0; i < keys.length; i++) {
      var v = bodyData[keys[i]]
      var t = typeof (v)
      var type = vtString
      if (t === 'string') {
        type = vtString
      } else if (t === 'number') {
        type = (v + '').indexOf('.') !== -1 ? vtExtended : vtInteger
      } else if (t === 'boolean') {
        type = vtBoolean
      } else if (t === 'object') {
        if (v instanceof Array) {
          type = typeof (v[0]) === 'number' ? vtInt64 : vtObject
        } else if (v.type === 'hex') {
          type = vtPointer
          v = v.data
        } else if (v.type === 'sqltable') {
          type = vtTable
          v = this.getSocketTable(v.field, v.data)
        }
      }
      res.push({
        Name: keys[i],
        Value: v,
        Type: type
      })
    }
    return res
  }

  /**
   * @description  将socket Table类型的数据转换为vPar 可以解析的类型
   * @param {Object} fields 头
   * @param {Object} data 数据
   */
  this.getSocketTable = function(fields, data) {
    var res = []
    var indexObj = {}
    for (var i = 0; i < fields.length; i++) {
      var t = fields[i].Type
      // eslint-disable-next-line no-eval
      fields[i].Type = eval('vt' + t.replace(/^./, t[0].toUpperCase()))
      indexObj[fields[i].Name] = i
    }
    res.push(fields)

    for (let i = 0; i < data.length; i++) {
      var ks = Object.keys(data[i])
      var row = []
      for (var j = 0; j < ks.length; j++) {
        row[indexObj[ks[j]]] = {
          Value: data[i][ks[j]]
        }
      }
      res.push(row)
    }
    return res
  }
  this.init()
}
export function SQLTable(data) {
  this.dataJson = data
  this.dataRow = 0

  // rowCount
  if (!(this.dataJson) || this.dataJson.length === 0) {
    this.rowCount = 0
  } else {
    this.rowCount = this.dataJson.length - 1
  }
  // colCount
  if (!(this.dataJson) || this.dataJson.length === 0) {
    this.colCount = 0
  } else {
    this.colCount = this.dataJson[0].length
  }

  this.getRowCount = function() {
    return this.rowCount
  }

  this.getColCount = function() {
    return this.colCount
  }

  this.eof = function() {
    return this.dataRow >= this.rowCount
  }

  this.bof = function() {
    return this.dataRow <= 0
  }

  this.first = function() {
    if (this.rowCount > 0) {
      this.dataRow = 0
      return true
    }
    return false
  }

  this.last = function() {
    if (this.rowCount > 0) {
      this.dataRow = this.rowCount - 1
      return true
    }
    return false
  }

  this.move = function(row) {
    if (this.rowCount > 0 && this.rowCount > row) {
      this.dataRow = row
      return true
    }
    return false
  }

  this.next = function() {
    if (!this.eof()) {
      this.dataRow++
      return true
    }
    return false
  }

  this.previous = function() {
    if (!this.bof()) {
      this.dataRow--
      return true
    }
    return false
  }

  this.getValueByIndex = function(index) {
    if (this.dataRow < this.rowCount && index >= 0 && index < this.colCount) {
      return this.dataJson[this.dataRow + 1][index].Value
    } else {
      return null
    }
  }

  this.getFieldIndex = function(name) {
    if (!this.dataJson || this.dataJson.length === 0) {
      return -1
    }
    for (var i = 0; i < this.dataJson[0].length; i++) {
      if (this.dataJson[0][i].Name.toLowerCase() === name.toLowerCase()) {
        return i
      }
    }
    return -1
  }

  this.getValueByName = function(name) {
    return this.getValueByIndex(this.getFieldIndex(name))
  }

  this.getIntByName = function(name) {
    return parseInt(this.getValueByIndex(this.getFieldIndex(name)))
  }

  this.getFloatByName = function(name) {
    return parseFloat(this.getValueByIndex(this.getFieldIndex(name)))
  }

  this.getBlobStrByName = function(name) {
    return Global.hextoString(this.getValueByName(name))
  }

  this.locate = function(strFields, strValues) {
    var arr = strFields.split(';')

    this.first()
    while (!this.eof()) {
      var bRst = true
      for (var i = 0; i < arr.length; i++) {
        var value = strValues[i]
        if (typeof strValues[i] !== 'string') {
          value = strValues[i].toString()
        }
        if (!Global.SameText(this.getValueByName(arr[i]), value)) {
          bRst = false
          break
        }
      }
      if (bRst) {
        return true
      }
      this.next()
    }
    return false
  }

  this.delete = function() {
    if (!this.dataJson || this.dataJson.length === 0 || this.rowCount <= 0) {
      return false
    }
    this.dataJson.splice(this.dataRow + 1, 1)
    this.rowCount--
    this.first()
  }
}
